Add format attribute to printf-style wrappers and fix format string errors#123920
Add format attribute to printf-style wrappers and fix format string errors#123920
Conversation
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
…, str) pattern Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
| enable_no_gc_region_callback_status gc_heap::enable_no_gc_callback(NoGCRegionCallbackFinalizerWorkItem* callback, uint64_t callback_threshold) | ||
| { | ||
| dprintf(1, ("[no_gc_callback] calling enable_no_gc_callback with callback_threshold = %llu\n", callback_threshold)); | ||
| dprintf(1, ("[no_gc_callback] calling enable_no_gc_callback with callback_threshold = %lu\n", callback_threshold)); | ||
| enable_no_gc_region_callback_status status = enable_no_gc_region_callback_status::succeed; |
There was a problem hiding this comment.
callback_threshold is a uint64_t, but it is logged with %lu here. On LLP64 platforms (Windows), unsigned long is 32-bit, so this truncates the value and (with the new format checking) can trigger a format/type warning. Use PRIu64 (or %llu with an explicit cast to unsigned long long) for this argument.
| if (dd_new_allocation (hp->dynamic_data_of (soh_gen0)) <= (ptrdiff_t)soh_withheld_budget) | ||
| { | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of soh budget= %llu\n", soh_withheld_budget)); | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of soh budget= %lu\n", soh_withheld_budget)); | ||
| status = insufficient_budget; | ||
| } | ||
| if (dd_new_allocation (hp->dynamic_data_of (loh_generation)) <= (ptrdiff_t)loh_withheld_budget) | ||
| { | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of loh budget= %llu\n", loh_withheld_budget)); | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of loh budget= %lu\n", loh_withheld_budget)); | ||
| status = insufficient_budget; |
There was a problem hiding this comment.
soh_withheld_budget/loh_withheld_budget are size_t but are logged with %lu. This is not portable (on Windows size_t is 64-bit but unsigned long is 32-bit) and will also be flagged by the new printf format validation. Use %zu (or cast to an appropriately sized unsigned type) for these values.
| LOG((LF_GC, level, " Handles Scanned = %llu\n", pTable->_DEBUG_TotalHandlesActuallyScanned [i])); | ||
| LOG((LF_GC, level, " Blocks Examined = %ld\n", pTable->_DEBUG_TotalBlocksScannedNonTrivially[i])); | ||
| LOG((LF_GC, level, " Slots Scanned = %ld\n", pTable->_DEBUG_TotalHandleSlotsScanned [i])); | ||
| LOG((LF_GC, level, " Handles Scanned = %ld\n", pTable->_DEBUG_TotalHandlesActuallyScanned [i])); |
There was a problem hiding this comment.
totalBlocksScanned is declared as int64_t, but is printed using %ld (and the related per-generation counters are printed with %ld too). On Windows long is 32-bit, so this truncates and is a format/type mismatch under printf checking. Use PRId64/PRIi64 (or %lld with casts to long long) consistently for these 64-bit counters.
| uint64_t elapsed = GetHighPrecisionTimeStamp () - start_us; | ||
|
|
||
| dprintf (8888, ("rethreaded %Id items, merging took %I64dus (%I64dms)", | ||
| dprintf (8888, ("rethreaded %zd items, merging took %ldus (%ldms)", | ||
| total_num_fl_items_rethreaded_stage2, elapsed, (elapsed / 1000))); |
There was a problem hiding this comment.
elapsed is a uint64_t, but the log uses %ldus/%ldms. This is non-portable (Windows long is 32-bit) and will be flagged by printf format validation. Prefer PRIu64 (or %llu with casts) for the timestamp and derived values.
| dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[dynamic_heap_count_data.sample_index]; | ||
| wait_time = min (wait_time, (uint32_t)(sample.elapsed_between_gcs / 1000 / 3)); | ||
| wait_time = max (wait_time, 1u); | ||
|
|
||
| dprintf (6666, ("gc#0 thread waiting for %d ms (betwen GCs %I64d)", wait_time, sample.elapsed_between_gcs)); | ||
| dprintf (6666, ("gc#0 thread waiting for %d ms (betwen GCs %ld)", wait_time, sample.elapsed_between_gcs)); | ||
| } |
There was a problem hiding this comment.
sample.elapsed_between_gcs is a uint64_t (see dynamic_heap_count_data_t::sample in gcpriv.h), but is logged here with %ld. This truncates on LLP64 and is a format/type mismatch with the new printf validation. Use PRIu64 (or %llu with cast to unsigned long long) when printing this value.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- jitinterface.cpp: Fix INT64 delta with %08x -> %08" PRIx64 " with (uint64_t) cast - ceeload.cpp: Fix size_t args with %lx -> %zx - arm64/singlestepper.cpp: Fix uint64_t values with %lx -> %" PRIx64 " (5 LOG calls) - loongarch64/singlestepper.cpp: Same fixes as arm64 (5 LOG calls) - riscv64/singlestepper.cpp: Same fixes as arm64 (5 LOG calls) Added #include <inttypes.h> where needed for PRIx64 macro. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace non-portable format specifiers (%ld, %lu) with portable alternatives using <inttypes.h> macros: - uint64_t: use PRIu64 macro via string concatenation - int64_t: use PRId64 macro via string concatenation - size_t: use %zu (unsigned) Files fixed: dynamic_heap_count.cpp, collect.cpp, init.cpp, no_gc.cpp, plan_phase.cpp, handletable.cpp, allocation.cpp Added #include <inttypes.h> to env/common.h (standalone GC build), gcpriv.h (coreclr VM build), and handletable.cpp (standalone compilation). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Annotate log_init_error_to_host, LogErrorToHost, _MulticoreJitTrace, FormatString, CrashInfo::Trace, CrashInfo::TraceVerbose, trace_printf, trace_verbose_printf, printf_status, and printf_error with MINIPAL_ATTR_FORMAT_PRINTF so the compiler checks format strings. Fix format mismatches found by the new annotations: - crashinfomac.cpp: cast pages_resident to unsigned long long for %llx; use %zd/%lu for size_t/ssize_t/vm_size_t args - createdumpmain.cpp: use PRIu64 for uint64_t g_ticksPerMS and elapsed - createdumpunix.cpp: use %lu cast for PAGE_SIZE (vm_size_t) - dumpwritermacho.cpp: use %zu for size_t; use PRIu64 for uint64_t - interface.cpp: use %.3f for float ratio values in log_init_error_to_host Also fix pre-existing broken string literals in collect.cpp and dynamic_heap_count.cpp where trailing commas were inside the format string instead of separating it from arguments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…subsystems Fix format specifier/argument type mismatches caught by __attribute__((format)): GC: Fix %zd with uint64_t in card_table.cpp, dynamic_heap_count.cpp, dynamic_tuning.cpp, gc.cpp, init.cpp, mark_phase.cpp VM: Fix %p with PCODE/TADDR in arm64/stubs.cpp, %S with LPCWSTR in cdacstress.cpp, %p with PCODE in multicorejitplayer.cpp, MAKE_UTF8PTR_FROMWIDE for wide string in multicorejitplayer.cpp JIT: Fix %ld with INT64 in valuenum.cpp Debug: Fix %zx with ULONG_PTR/CORDB_ADDRESS in debug/di/ files, %zx with PRD_TYPE in controller.cpp/executioncontrol.cpp, %p with PCODE/TADDR in arm64/walker.cpp, %x with DT_CONTEXT*/SIZE_T in shared/arm64/primitives.cpp Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tribute-to-wrappers # Conflicts: # src/coreclr/debug/di/process.cpp # src/coreclr/debug/di/rsthread.cpp # src/coreclr/debug/ee/debugger.cpp # src/coreclr/debug/ee/debugger.inl # src/coreclr/debug/ee/debuggermodule.cpp # src/coreclr/jit/lower.cpp # src/coreclr/vm/dllimport.cpp
Fix %p format with guint64 tid arguments in g_error calls. Use G_GSIZE_FORMAT with (gsize) casts to match the existing convention in this file for printing thread IDs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- dllimport.cpp: Cast void* from CQuickBytes::Ptr() to (const char*) for %s - lower.cpp: Cast int64_t to (long long) to match %lld on LP64 platforms - util.cpp: Use %p with (void*) cast instead of %x with SIZE_T* pointers - excep.cpp: Cast PCODE/TADDR to (void*) for %p format specifier Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
createdump: Move #include <inttypes.h> outside #ifdef HOST_UNIX in createdump.h so PRIu64/PRIx64 are available on Windows. Fix %llx with uint64_t (unsigned long on LP64) in crashinfounix.cpp and crashinfo.cpp — use PRIx64 instead. mono: Fix C4312 warning in mono-threads-state-machine.c by replacing (void*) cast of MonoNativeThreadId with (gsize) cast and G_GSIZE_FORMAT. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| if (!ValidateModuleName(libFileName)) | ||
| { | ||
| LOG((LF_GC, LL_INFO100, "Invalid GC name found %s\n", libFileName)); | ||
| LOG((LF_GC, LL_INFO100, "Invalid GC name found %p\n", libFileName)); | ||
| return nullptr; |
There was a problem hiding this comment.
This log now uses "%p" for libFileName, which prints the pointer address rather than the invalid module name. That makes the diagnostic much less useful. Consider converting libFileName to UTF-8 (similar to later libPath.GetUTF8()) and logging it with "%s", or otherwise logging the actual string value.
| #include "common.h" | ||
| #include <inttypes.h> | ||
| #include "riscv64singlestepper.h" |
There was a problem hiding this comment.
PRIx64 comes from <inttypes.h>, but in C++ builds some standard libraries (notably glibc) only define the PRI* format macros when __STDC_FORMAT_MACROS is defined before including the header. To avoid portability/build breaks, consider defining __STDC_FORMAT_MACROS (guarded) before including <inttypes.h> here (or include an existing header that does so).
| #include "common.h" | ||
| #include <inttypes.h> | ||
| #include "arm64singlestepper.h" |
There was a problem hiding this comment.
Same portability concern as other PRI-macro changes: in C++ mode <inttypes.h> may not expose PRIx64 unless __STDC_FORMAT_MACROS is defined before the include. Please ensure this is defined (guarded) prior to including <inttypes.h> so the PRIx64 usages below compile on all Unix libc implementations.
| #include "common.h" | ||
| #include <inttypes.h> | ||
| #include "loongarch64singlestepper.h" |
There was a problem hiding this comment.
Same issue as other PRI-macro additions: for C++ compilation, <inttypes.h> may not define PRIx64 unless __STDC_FORMAT_MACROS is set before including it (common on glibc). Please ensure __STDC_FORMAT_MACROS is defined (guarded) before this include to avoid build breaks.
| #include "common.h" | ||
| #include <inttypes.h> | ||
| #include "jitinterface.h" |
There was a problem hiding this comment.
This file now includes <inttypes.h> to use PRIx64, but in C++ builds those PRI* macros may be hidden unless __STDC_FORMAT_MACROS is defined before including the header (notably on glibc). Please ensure __STDC_FORMAT_MACROS is defined (guarded) before the <inttypes.h> include to keep Linux builds working.
|
|
||
| #include <inttypes.h> | ||
| #include "codegen.h" |
There was a problem hiding this comment.
<inttypes.h> is included here for PRI* format macros, but in C++ mode some libcs only provide those macros when __STDC_FORMAT_MACROS is defined before the include. Please ensure __STDC_FORMAT_MACROS is defined (guarded) prior to including <inttypes.h> so these PRIu64/PRId64 uses compile portably.
| #include "common.h" | ||
| #include <limits> | ||
|
|
||
| #include <inttypes.h> | ||
| #include "stubgen.h" | ||
| #include "jitinterface.h" |
There was a problem hiding this comment.
This translation unit now relies on PRI* macros via <inttypes.h>, but in C++ builds they may not be visible unless __STDC_FORMAT_MACROS is defined before the include (common on glibc). Please define __STDC_FORMAT_MACROS (guarded) before including <inttypes.h> to avoid portability/build issues.
| JITLOG_THIS(m_RootCompiler, | ||
| (LL_INFO100000, "Inline %s profitable: benefit=%g (perCall=%g, local=%g, global=%g, size=%g)\n", | ||
| shouldInline ? "is" : "is not", benefit, perCallBenefit, localBenefit, globalImportance, | ||
| (double)m_PerCallInstructionEstimate / SIZE_SCALE, (double)m_ModelCodeSizeEstimate / SIZE_SCALE)); | ||
| (double)m_PerCallInstructionEstimate / SIZE_SCALE)); |
There was a problem hiding this comment.
The log label size=%g is currently printing m_PerCallInstructionEstimate / SIZE_SCALE, which is an instruction-count estimate rather than the size impact (and doesn’t match the size label). This looks like an accidental argument change when fixing the varargs mismatch—should likely print m_ModelCodeSizeEstimate / SIZE_SCALE, or update the format string to include both instruction and size estimates explicitly.
- crashinfounix.cpp: Use PRIx64 directly for uint64_t address (PRIx is PRIx32 on 32-bit) - objecthandle.cpp: Fix LOG_OBJECT_CLASS string concat (remove stray comma) - compiler.cpp: Use %p with (void*) cast for CORINFO_CLASS_HANDLE pointer - gcenv.ee.common.cpp: Cast PCODE/TADDR to (void*) for %p on x86 - wasm/helpers.cpp: Cast TADDR to (void*) for %p on wasm - tramp-amd64.c: Fix g_assertf format to match all 4 arguments - transform.c: Cast ptrdiff_t to (int) for %d/%x format specifiers - jiterpreter.c: Cast function pointer to (int)(gsize) for %d format - mini-arm64.c: Cast ptrdiff_t to (int) for %d format Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…attribute-to-wrappers # Conflicts: # src/coreclr/vm/jithelpers.cpp
Use PRIx64 directly for uint64_t variables (start, pagemapOffset, value) instead of PRIx which expands to PRIx32 on 32-bit targets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| } | ||
|
|
||
| trace::verbose(_X("Reading from host interface version: [0x%04zx:%zd] to initialize policy version: [0x%04x:%d]"), input->version_hi, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_HI, HOST_INTERFACE_LAYOUT_VERSION_LO); | ||
| trace::verbose(_X("Reading from host interface version: [0x%04zx:%zd] to initialize policy version: [0x%04x:%zu]"), input->version_hi, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_HI, (size_t)HOST_INTERFACE_LAYOUT_VERSION_LO); |
There was a problem hiding this comment.
input->version_lo is a size_t (see host_interface_t), but this log uses %zd (signed). With the new printf-format annotations on trace::verbose, this should be %zu (or cast to ssize_t if negative values are intended).
| trace::error(_X("The size of the data layout used to initialize %s is %zd; expected at least %zu"), LIBHOSTPOLICY_NAME, input->version_lo, | ||
| (size_t)(offsetof(host_interface_t, host_mode) + sizeof(input->host_mode))); |
There was a problem hiding this comment.
input->version_lo is size_t, but the error message formats it with %zd. This should be %zu to match the type and avoid incorrect output / format warnings now that trace::error is printf-annotated.
| if (G_UNLIKELY (res != 0 && res != ETIMEDOUT)) { | ||
| g_print ("cond: %p mutex: %p\n", *(gpointer*)cond, *(gpointer*)mutex); | ||
| g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %ld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms); | ||
| g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %lld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms); |
There was a problem hiding this comment.
The g_error format string uses %lld for ts.tv_sec, but tv_sec is time_t (commonly long), and this call doesn't cast it. Please either use the correct specifier for time_t (e.g., %ld where applicable) or cast ts.tv_sec to long long to match %lld to avoid varargs type mismatch.
- debug/ee/amd64/walker.cpp: %0.2x -> %02x (GCC redundant 0 flag) - vm/arm/stubs.cpp: (void*)(size_t) casts for TADDR with %p on arm32 - vm/i386/cgenx86.cpp: (void*)(size_t) casts for TADDR with %p on x86 - vm/exceptionhandling.cpp: (void*)(size_t) casts in FIXUPREG macro - gc/interface.cpp: STRESS_LOG_VA -> STRESS_LOG0 (format-security) - jit/emitriscv64.cpp: Fix stray comma before FMT_BB string concat - jit/emitloongarch64.cpp: %08X/%llx/%lx -> %p/PRIx64/%x for portability Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| case ShortInlineVar: | ||
| case ShortInlineI: | ||
| case InlineI: | ||
| strArgument.Printf("0x%p", pInstruction->uArg); | ||
| strArgument.Printf("0x%lx", (unsigned long)pInstruction->uArg); | ||
| break; |
There was a problem hiding this comment.
In DumpILInstruction, pInstruction->uArg is UINT_PTR. Formatting it via 0x%lx / 0x%08lx after casting to unsigned long can truncate on Windows 64-bit (where unsigned long is 32-bit) and reintroduces platform-specific formatting. Prefer printing UINT_PTR via PRIxPTR (with a uintptr_t cast) or another pointer-width specifier used elsewhere in the repo (e.g., %zx with (size_t)), so the value is correct on all targets.
| case InlineTok: | ||
| // No token value when we dump IL for ETW | ||
| if (pDumpILStubCode == NULL) | ||
| strArgument.Printf("0x%08p", pInstruction->uArg); | ||
| strArgument.Printf("0x%08lx", (unsigned long)pInstruction->uArg); | ||
|
|
There was a problem hiding this comment.
This 0x%08lx formatting has the same UINT_PTR truncation risk as above on Win64 (where unsigned long is 32-bit). Even if current opcodes typically use 32-bit tokens here, using a pointer-width-safe format (or explicitly casting down to uint32_t when that’s the intent) would avoid future issues and keeps the printf-attribute checking accurate.
| if (!ValidateModuleName(libFileName)) | ||
| { | ||
| LOG((LF_GC, LL_INFO100, "Invalid GC name found %s\n", libFileName)); | ||
| LOG((LF_GC, LL_INFO100, "Invalid GC name found %p\n", libFileName)); | ||
| return nullptr; | ||
| } |
There was a problem hiding this comment.
The log message now prints the pointer value of libFileName (%p) rather than the invalid GC module name/path itself, which makes the diagnostic much less useful. Since libFileName is LPCWSTR, consider converting to UTF-8 (e.g., MAKE_UTF8PTR_FROMWIDE) and logging it with %s, similar to the other standalone GC logging in this file.
| res = pthread_cond_timedwait (cond, mutex, &ts); | ||
| if (G_UNLIKELY (res != 0 && res != ETIMEDOUT)) { | ||
| g_print ("cond: %p mutex: %p\n", *(gpointer*)cond, *(gpointer*)mutex); | ||
| g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %ld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms); | ||
| g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %lld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms); | ||
| } |
There was a problem hiding this comment.
ts.tv_sec is time_t (not necessarily long long). Using %lld here without casting can be UB and will still trigger format warnings on platforms where time_t is long (common on Linux). Consider either using %ld consistently, or cast ts.tv_sec to long long (and do the same in the pthread_cond_timedwait_relative_np branch) or use an inttypes.h/GLib format macro with an explicit cast.
| void ERR_new(void); | ||
| void ERR_set_debug(const char *file, int line, const char *func); | ||
| void ERR_set_error(int lib, int reason, const char *fmt, ...); | ||
| void ERR_set_error(int lib, int reason, const char *fmt, ...) | ||
| #ifdef __GNUC__ | ||
| __attribute__ ((__format__(__printf__, 3, 4))) | ||
| #endif | ||
| ; |
There was a problem hiding this comment.
This header adds a new __GNUC__ / __attribute__((format)) block directly on ERR_set_error, even though the PR introduces MINIPAL_ATTR_FORMAT_PRINTF to centralize this pattern. If feasible for this component, prefer using the shared macro (and include the header that defines it) so format-attribute usage stays consistent and avoids duplicated compiler-ifdefs.
| if (magic == FAT_MAGIC) | ||
| { | ||
| m_offset_in_file = OSSwapBigToHostInt32(*(uint32_t*)offset_in_FAT_universal_binary<fat_arch>(base_ptr)); | ||
| trace::info(_X("FAT container detected. Offset in file:[%lx]"), m_offset_in_file); | ||
| trace::info(_X("FAT container detected. Offset in file:[%llx]"), (long long)m_offset_in_file); | ||
| } |
There was a problem hiding this comment.
%llx expects an unsigned long long, but m_offset_in_file is int64_t and is currently cast to long long. With the new printf-format checking enabled on trace::info, this can still warn and is technically UB. Prefer casting to unsigned long long (or uint64_t + PRIx64) to match the specifier.
| else if (magic == FAT_MAGIC_64) | ||
| { | ||
| m_offset_in_file = OSSwapBigToHostInt64(*(uint64_t*)offset_in_FAT_universal_binary<fat_arch_64>(base_ptr)); | ||
| trace::info(_X("FAT64 container detected. Offset in file:[%lx]"), m_offset_in_file); | ||
| trace::info(_X("FAT64 container detected. Offset in file:[%llx]"), (long long)m_offset_in_file); | ||
| } |
There was a problem hiding this comment.
Same issue as above: %llx expects unsigned long long, but the argument is cast to long long while m_offset_in_file is int64_t. Consider using an unsigned cast (or PRIx64) to align the argument type with the format specifier and avoid UB/warnings.
Description
Enabled compiler validation of printf-style format strings by adding
__attribute__ ((format (printf, ...)))to wrapper functions. Fixed 85+ format string errors discovered by the compiler across CoreCLR, Mono, and Corehost. Merged with latest main branch to ensure compatibility with recent changes.Changes
Centralized format attribute macro in
src/native/minipal/types.h:MINIPAL_ATTR_FORMAT_PRINTF(fmt_pos, arg_pos)macro for consistent usage across the codebase#ifdef __GNUC__blocks throughout the codebaseAdded format attributes to 60+ wrapper functions across 13 headers using
MINIPAL_ATTR_FORMAT_PRINTF:src/native/minipal/types.h- CentralizedMINIPAL_ATTR_FORMAT_PRINTFmacro definitionsrc/native/minipal/log.h-minipal_log_printsrc/native/corehost/hostmisc/trace.h-trace::verbose,info,warning,error,printlnsrc/native/libs/Common/pal_compiler.h-do_abort_unlesssrc/native/libs/System.Native/pal_string.h-SystemNative_SNPrintFsrc/native/libs/System.Security.Cryptography.Native/osslcompat_30.h-ERR_set_errorsrc/coreclr/inc/log.h-LogSpew,LogSpew2,LogSpewAlwayssrc/coreclr/inc/stresslog.h-StressLog::LogMsg,ThreadStressLog::LogMsgsrc/coreclr/inc/sstring.h-Printf,AppendPrintfsrc/coreclr/jit/host.h-jitprintf,logf,flogf,gcDump_logfsrc/coreclr/jit/compiler.h-printfAlloc,JitLogEEsrc/coreclr/gc/gc.h-GCLogsrc/coreclr/gc/gcpriv.h-GCLogConfigsrc/mono/mono/eglib/glib.h-g_error_new,g_set_error,g_print,g_printerr,g_log,g_assertion_message,g_async_safe_*Fixed 85+ format string errors across 24 source files:
%I64d/%Id→%zd/%zuPRIX64/PRIx64/PRIu64from<inttypes.h>#and0flags(void*)cast for pointersprintf(str)→printf("%s", str)thisFiles with format errors fixed:
Added missing header includes:
src/coreclr/ildasm/ildasmpch.h- Added#include <inttypes.h>for PRI macrossrc/coreclr/tools/metainfo/mdinfo.cpp- Added#include <inttypes.h>for PRI macrossrc/coreclr/vm/jitinterface.cpp- Added#include <inttypes.h>for PRI macrossrc/coreclr/jit/gentree.cpp- Added#include <inttypes.h>for PRI macrosMerged from main:
Review feedback addressed:
src/coreclr/vm/crst.cpp: Simplified format strings to avoid unnecessary line splitssrc/coreclr/gc/diagnostics.cpp: Removed unnecessary size_t casts (type already size_t)%zuinstead of%zdfor unsigned size_t%lldback to%dfor INT32 typeExample fixes:
Impact
#ifdef __GNUC__blocks via centralizedMINIPAL_ATTR_FORMAT_PRINTFmacro; restored original indentation to keep git history clean💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.